home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / c / xw2.000 / xw2 / xw / csource / directory.c next >
Encoding:
C/C++ Source or Header  |  1994-07-01  |  12.7 KB  |  429 lines

  1.  
  2. #define SYSV
  3.  
  4. /*{{{  Copyleft*/
  5.  
  6. /*
  7.  *
  8.  *      Created: 2.3.1993
  9.  *      H.Maroske
  10.  *      H"ohenweg 32
  11.  *      7760 Radolfzell
  12.  *
  13.  *      Thanks go to
  14.  *
  15.  *      Win Treese
  16.  *      Cambridge Research Lab
  17.  *      Digital Equipment Corporation
  18.  *      treese@crl.dec.com
  19.  *
  20.  *      $Source: /trx/u2/treese/Src/Xdir.rel/RCS/xdir.c,v $
  21.  *
  22.  *          COPYRIGHT 1990
  23.  *        DIGITAL EQUIPMENT CORPORATION
  24.  *         MAYNARD, MASSACHUSETTS
  25.  *        ALL RIGHTS RESERVED.
  26.  *
  27.  * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
  28.  * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
  29.  * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE
  30.  * FOR ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED
  31.  * WARRANTY.
  32.  *
  33.  * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT
  34.  * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN
  35.  * ADDITION TO THAT SET FORTH ABOVE.
  36.  *
  37.  * Permission to use, copy, modify, and distribute this software and its
  38.  * documentation for any purpose and without fee is hereby granted, provided
  39.  * that the above copyright notice appear in all copies and that both that
  40.  * copyright notice and this permission notice appear in supporting
  41.  * documentation, and that the name of Digital Equipment Corporation not be
  42.  * used in advertising or publicity pertaining to distribution of the
  43.  * software without specific, written prior permission.
  44.  *
  45.  *      Modified: 4 Dec 91 - Paul King (king@cs.uq.oz.au)
  46.  */
  47.  
  48. /*}}}  */
  49. /*{{{  Includes*/
  50.  
  51. #include <stdlib.h>
  52. #include <stdio.h>
  53. #include <string.h>
  54. #include <sys/types.h>
  55. #include <sys/param.h>
  56. #include <sys/stat.h>
  57. #include <dirent.h>
  58.  
  59. /*}}}  */
  60.  
  61. #define INVERT '!'
  62. char *XbWFTb_PckTxt(char *);
  63. /*{{{  Globale Variablen*/
  64.  
  65.  int      file_entry_cnt, dir_entry_cnt;
  66.  char    **file_list, **dir_list;
  67.  char    **filelist, **dirlist;
  68.  
  69.  
  70.  typedef struct{
  71.    char cur_dir[200];
  72.    char dirmask[200];
  73.    int NoDirt;
  74.    int NoBackups;
  75.    int NoUnknown;
  76.    int NENTRIES;
  77.    }
  78.    SETUPS;
  79.  
  80.  SETUPS SETUP = {
  81.    "",
  82.    "",
  83.    0,
  84.    0,
  85.    0,
  86.    200,
  87.    };
  88.  
  89.  
  90. /*}}}  */
  91. int XbWSSy_FindFirstNr=0;
  92. int wild_match(char *string, char *pattern);
  93.  
  94. /*{{{  Search for Directory- and Filenames    * * * * * * * * * * **/
  95. /*{{{  void MakeFullPath(char *root, char *filename, char *pathname){*/
  96. /*{{{  Beschreibung*/
  97. /* Function:    MakeFullPath() creates the full pathname for the given file.
  98.  * Arguments:   filename:       Name of the file in question.
  99.  *              pathname:       Buffer for full name.
  100.  * Returns:     Nothing.
  101.  * Notes:
  102.  */
  103. /*}}}  */
  104. void MakeFullPath(char *root, char *filename, char *pathname){
  105.   strcpy(pathname, root);
  106.   strcat(pathname, "/");
  107.   strcat(pathname, filename);
  108.   }
  109. /*}}}  */
  110. /*{{{  int IsDirectory(char *root, char *path){*/
  111. /*{{{  Beschreibung*/
  112. /* Function:    IsDirectory() tests to see if a pathname is a directory.
  113.  * Arguments:   path:   Pathname of file to test.
  114.  * Returns:     True (1) or False (0).
  115.  * Notes:       False is returned if the directory is not accessible.
  116.  */
  117. /*}}}  */
  118. int IsDirectory(char *root, char *path){
  119.     char            fullpath[MAXPATHLEN];
  120.     struct stat     statbuf;
  121.     if (path == NULL)
  122.         return (0);
  123.     MakeFullPath(root, path, fullpath);
  124.     if (stat(fullpath, &statbuf))       /* some error, report that it is not
  125.                                          * a directory */
  126.         return (0);
  127.     if (statbuf.st_mode & S_IFDIR)
  128.         return (1);
  129.     else
  130.         return (0);
  131. }
  132. /*}}}  */
  133. /*{{{  int IsLink(char *root, char *path){*/
  134. int IsLink(char *root, char *path){
  135.   char            fullpath[MAXPATHLEN];
  136.   struct stat     statbuf;
  137.   if (path == NULL) {return (0);};
  138.   MakeFullPath(root, path, fullpath);
  139.   if (IsDirectory(root,path)){
  140.     return(0);
  141.     }
  142.   else {
  143.     if (lstat(fullpath, &statbuf)){
  144.       return(0);
  145.       };
  146.     if (statbuf.st_mode & S_IFLNK == S_IFLNK){
  147.       return (1);
  148.       }
  149.     else {
  150.       return (0);
  151.       };
  152.     };
  153.   };
  154.  
  155. /*}}}  */
  156. /*{{{  int IsExecutable(char *root, char *path){*/
  157. int IsExecutable(char *root, char *path){
  158.     char            fullpath[MAXPATHLEN];
  159.     struct stat     statbuf;
  160.     if (path == NULL)
  161.         return (0);
  162.     MakeFullPath(root, path, fullpath);
  163.     if (stat(fullpath, &statbuf))       /* some error, report that it is not
  164.                                          * a directory */
  165.         return (0);
  166.     if (statbuf.st_mode & S_IXUSR)
  167.         return (1);
  168.     else
  169.         return (0);
  170. }
  171. /*}}}  */
  172. /*{{{  static int star(char *string, char *pattern){*/
  173. /* Return nonzero if `string' matches Unix-style wildcard pattern
  174.    `pattern'; zero if not. */
  175. static int star(char *string, char *pattern){
  176.   while (wild_match(string, pattern) == 0)
  177.     if (*++string == '\0')
  178.       return 0;
  179.   return 1;
  180.   }
  181. /*}}}  */
  182. /*{{{  int wild_match(char *string, char *pattern){*/
  183. /*{{{  Beschreibung*/
  184. /* wildmatch.c - Unix-style command line wildcards
  185.  
  186.    This procedure is in the public domain.
  187.  
  188.    After that, it is just as if the operating system had expanded the
  189.    arguments, except that they are not sorted.  The program name and all
  190.    arguments that are expanded from wildcards are lowercased.
  191.  
  192.    Syntax for wildcards:
  193.    *            Matches zero or more of any character (except a '.' at
  194.                 the beginning of a name).
  195.    ?            Matches any single character.
  196.    [r3z]        Matches 'r', '3', or 'z'.
  197.    [a-d]        Matches a single character in the range 'a' through 'd'.
  198.    [!a-d]       Matches any single character except a character in the
  199.                 range 'a' through 'd'.
  200.  
  201.    The period between the filename root and its extension need not be
  202.    given explicitly.  Thus, the pattern `a*e' will match 'abacus.exe'
  203.    and 'axyz.e' as well as 'apple'.  Comparisons are not case sensitive.
  204.  
  205.    The wild_match code was written by Rich Salz, rsalz@bbn.com,
  206.    posted to net.sources in November, 1986.
  207.  
  208.    The code connecting the two is by Mike Slomin, bellcore!lcuxa!mike2,
  209.    posted to comp.sys.ibm.pc in November, 1988.
  210.  
  211.    Major performance enhancements and bug fixes, and source cleanup,
  212.    by David MacKenzie, djm@ai.mit.edu. */
  213.  
  214. /* Shell-style pattern matching for ?, \, [], and * characters.
  215.    I'm putting this replacement in the public domain.
  216.  
  217.    Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. */
  218. /*}}}  */
  219. int wild_match_sub(char *string, char *pattern){
  220.     int             prev;       /* Previous character in character class. */
  221.     int             matched;    /* If 1, character class has been matched. */
  222.     int             reverse;    /* If 1, character class is inverted. */
  223.     for (; *pattern; string++, pattern++)
  224.         switch (*pattern) {
  225.         case '\\':
  226.             /* Literal match with following character; fall through. */
  227.             pattern++;
  228.         default:
  229.             if (*string != *pattern)
  230.                 return 0;
  231.             continue;
  232.         case '?':
  233.             /* Match anything. */
  234.             if (*string == '\0')
  235.                 return 0;
  236.             continue;
  237.         case '*':
  238.             /* Trailing star matches everything. */
  239.             return *++pattern ? star(string, pattern) : 1;
  240.         case '[':
  241.             /* Check for inverse character class. */
  242.             reverse = pattern[1] == INVERT;
  243.             if (reverse)
  244.                 pattern++;
  245.             for (prev = 256, matched = 0; *++pattern && *pattern != ']';
  246.                  prev = *pattern)
  247.                 if (*pattern == '-'
  248.                     ? *string <= *++pattern && *string >= prev
  249.                     : *string == *pattern)
  250.                     matched = 1;
  251.             if (matched == reverse)
  252.                 return 0;
  253.             continue;
  254.         }
  255.     return *string == '\0';
  256. }
  257.  
  258. int wild_match(char *string, char *pattern){
  259.   char sstr[200], substr[100];
  260.   int ret;
  261.   strcpy(sstr,XbWFTb_PckTxt(pattern));
  262.   while(strlen(sstr) > 0){
  263.     if (strchr(sstr,' ') != NULL){
  264.       strcpy(substr,sstr);
  265.       strcpy(strchr(substr,' '),"\0");
  266.       ret=wild_match_sub(string, substr);
  267.       if (ret){return(ret);};
  268.       strcpy(sstr,XbWFTb_PckTxt(strchr(sstr,' ')));
  269.       }
  270.     else {
  271.       return(wild_match_sub(string,sstr));
  272.       };
  273.     };
  274.   return(0);
  275.   };
  276. /*}}}  */
  277. /*{{{  SPComp() compares two string pointers for qsort().*/
  278. /* Function:    SPComp() compares two string pointers for qsort().
  279.  * Arguments:   s1, s2: strings to be compared.
  280.  * Returns:     Value of strcmp().
  281.  * Notes:
  282.  */
  283. int SPComp(char **s1, char **s2){
  284.   return (strcmp(*s1, *s2));
  285.   }
  286. /*}}}  */
  287. /*{{{  char *SaveString(char *string){*/
  288. char *SaveString(char *string){
  289.   char           *new;
  290.   new = (char *) malloc(strlen(string) + 1);
  291.   strcpy(new, string);
  292.   return (new);
  293.   }
  294. /*}}}  */
  295. /*{{{  long MakeFileList(*/
  296. long MakeFileList(
  297.     char *dir_name,
  298.     char *mask,
  299.     char ***dir_list,
  300.     char ***file_list){
  301.  
  302.     DIR            *dirp;
  303.     struct dirent  *dp;
  304.     char          **cur_file, **cur_directory;
  305.     char          **last_file, **last_dir;
  306.  
  307.     cur_file = filelist;
  308.     cur_directory = dirlist;
  309.     last_file = filelist + file_entry_cnt - 1;
  310.     last_dir = dirlist + dir_entry_cnt - 1;
  311.  
  312.     dirp = opendir(dir_name);
  313.     if (dirp == NULL) {
  314.         *file_list = filelist;
  315.         *file_list[0]="";
  316.         *dir_list = dirlist;
  317.         *dir_list[0]="..";
  318.         return (0);
  319.     }
  320.     /* process any events to ensure cursor is set to wait_cursor */
  321.     /*
  322.      * don't do this inside the following loop because this procedure could
  323.      * be re-entered if the user presses (e.g.) rescan
  324.      */
  325.  
  326.     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  327.         /* skip over '.' (current dir) */
  328.         if (!strcmp(dp->d_name, "."))
  329.             continue;
  330.  
  331.         if (IsDirectory(dir_name, dp->d_name)) {
  332.             *cur_directory++ = SaveString(dp->d_name);
  333.             if (cur_directory == last_dir) {    /* out of space, make more */
  334.                 dirlist = (char **) realloc(dirlist,
  335.                                         2 * dir_entry_cnt * sizeof(char *));
  336.                 cur_directory = dirlist + dir_entry_cnt - 1;
  337.                 dir_entry_cnt = 2 * dir_entry_cnt;
  338.                 last_dir = dirlist + dir_entry_cnt - 1;
  339.             }
  340.         } else {
  341.             /* check if matches regular expression */
  342.             if ((mask == NULL) || (*mask == '\0'))
  343.                 mask = "*";
  344.             else if (*mask == '\0')
  345.                 mask = "*";
  346.             if (wild_match(dp->d_name, mask) == 0)
  347.                 continue;       /* no, do next */
  348.             if (SETUP.NoDirt){
  349.               /*if (GetFileType(dp->d_name) == F_TYPE_O){
  350.                 continue;
  351.                 };*/
  352.               };
  353.             if (SETUP.NoUnknown){
  354.               /*if (GetFileType(dp->d_name) == F_TYPE_UNKNOWN){
  355.                 continue;
  356.                 };*/
  357.               };
  358.             if (SETUP.NoBackups){
  359.               /*if (GetFileType(dp->d_name) == F_TYPE_BAK){
  360.                 continue;
  361.                 };*/
  362.               };
  363.             if (mask[0] == '*' && dp->d_name[0] == '.')
  364.                 continue;       /* skip files with leading . */
  365.             *cur_file++ = SaveString(dp->d_name);
  366.             if (cur_file == last_file) {        /* out of space, make more */
  367.                 filelist = (char **) realloc(filelist,
  368.                                        2 * file_entry_cnt * sizeof(char *));
  369.                 cur_file = filelist + file_entry_cnt - 1;
  370.                 file_entry_cnt = 2 * file_entry_cnt;
  371.                 last_file = filelist + file_entry_cnt - 1;
  372.             }
  373.         }
  374.     }
  375.     *cur_file = NULL;
  376.     *cur_directory = NULL;
  377.     {
  378.       if (cur_file != filelist) {
  379.         qsort(filelist, cur_file - filelist, sizeof(char *), SPComp);
  380.         };
  381.       if (cur_directory != dirlist) {
  382.         qsort(dirlist, cur_directory - dirlist, sizeof(char *), SPComp);
  383.         };
  384.       *file_list = filelist;
  385.       *dir_list = dirlist;
  386.       };
  387.     *file_list = filelist;
  388.     *dir_list = dirlist;
  389.     closedir(dirp);
  390.     return 1;
  391. }
  392.  
  393. /*}}}  */
  394. /*}}}  */
  395.  
  396. int XbWSSy_FindFirstInit=0;
  397. char *XbWSSy_FindFirst(char *directory, char *spec){
  398.   XbWSSy_FindFirstNr=0;
  399.   dir_entry_cnt = SETUP.NENTRIES;
  400.   file_entry_cnt = SETUP.NENTRIES;
  401.   if (!XbWSSy_FindFirstInit){
  402.     filelist = (char **) calloc(file_entry_cnt, sizeof(char *));
  403.     dirlist = (char **) calloc(dir_entry_cnt, sizeof(char *));
  404.     XbWSSy_FindFirstInit=1;
  405.     };
  406.  
  407.   strcpy(SETUP.dirmask,XbWSSy_ConvertFileName(spec));
  408.   strcpy(SETUP.cur_dir,XbWSSy_ConvertFileName(directory));
  409.  
  410.   if (MakeFileList(SETUP.cur_dir, SETUP.dirmask, &dir_list, &file_list) == 0){
  411.     printf("No files in directory?");
  412.     return(NULL);
  413.     };
  414.   XbWSSy_FindFirstNr=0;
  415.   return((char*)filelist[XbWSSy_FindFirstNr]);
  416.   };
  417.  
  418. char *XbWSSy_FindNext(void){
  419.   XbWSSy_FindFirstNr++;
  420.   if (XbWSSy_FindFirstNr >= SETUP.NENTRIES){return("...");};
  421.   return((char*)filelist[XbWSSy_FindFirstNr]);
  422.   };
  423.  
  424. /*{{{F ../xdesktop/desktop.c*/
  425. /*:::F ../xdesktop/desktop.c*/
  426. /*}}}  */
  427.  
  428.  
  429.